package xdu.lz.stage1_basic.chapter3_threadCommunicate;


public class ProduceConsumer5 {
    private int i;
    private final Object LOCK = new Object();
    private volatile boolean isProduced = false;

    public void produce() {
        synchronized (LOCK) {
            //如果已经生产，等待消费完毕后被通知
            while (isProduced) {
                try {
                    LOCK.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //如果没有生产，生产并通知消费者消费,并把生产置为true
            }
            //如果没有else会导致生产多个消费一个或者生产一个消费多次
            //此时把上面的if改为while可以接这个问题
            System.out.println(Thread.currentThread().getName() + "生产->" + (++i));
            LOCK.notifyAll();
            isProduced = true;

        }
    }

    public void consume() {
        synchronized (LOCK) {
            //没有生产，等待生产者生产 被通知
            while (!isProduced) {
                try {
                    LOCK.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //如果已经生产了，则消费，然后通知生产者生产,并把已经生产置为false
            //如果没有else会导致生产多个消费一个或者生产一个消费多次
            //此时把上面的if改为while可以接这个问题
            System.out.println(Thread.currentThread().getName() + "消费->" + i);
            LOCK.notifyAll();
            isProduced = false;

        }
    }

    public static void main(String[] args) {
        ProduceConsumer5 pc = new ProduceConsumer5();
        for (int i = 0; i < 3; i++) {
            new Thread(() -> {
                while (true) {
                    pc.produce();
                    try {
                        Thread.sleep(10L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "P" + i).start();

        }
        for (int i = 0; i < 3; i++) {
            new Thread(() -> {
                while (true) {
                    pc.consume();
                    try {
                        Thread.sleep(10L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "C" + i).start();

        }


    }
}
